package day12;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

/**
 * CompleteService
 */
public class CompleteServiceExample01 {

    public static void main(String[] args) {
        invokeTask();

    }

    public static void completionTask() {

        ExecutorService executorService = Executors.newCachedThreadPool();
        CompletionService<String> completionService = new ExecutorCompletionService<>(executorService);

        List<Callable<String>> list = callableList();

        list.forEach(completionService::submit);

        for (int i = 0; i < list.size(); i++) {
            try {
                // 获取返回结果，返回结果是从阻塞队列中拿取，哪个先完成返回哪个
                System.out.println(completionService.take().get());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
        executorService.shutdown();
    }

    public static void invokeTask() {

        ExecutorService executorService = Executors.newCachedThreadPool();
        List<Callable<String>> list = callableList();
        try {
            List<Future<String>> futures = executorService.invokeAll(list);
            futures.forEach(stringFuture -> {
                try {
                    // 拿取返回结果，获取结果的时间长短按照最长任务时间来计算
                    System.out.println(stringFuture.get());
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            });

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static List<Callable<String>> callableList() {
        return Arrays.asList(
                () -> {
                    TimeUnit.SECONDS.sleep(3);
                    System.out.println("3 seconds");
                    return "a";
                },
                () -> {
                    TimeUnit.SECONDS.sleep(5);
                    System.out.println("5 seconds");
                    return "b";
                },
                () -> {
                    TimeUnit.SECONDS.sleep(10);
                    System.out.println("10 seconds");
                    return "c";
                }
        );
    }
}
